﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.Linq;
using FileMonitor.Configuration.Providers;
using System.Collections.Specialized;
using FileMonitor.Configuration.Tool.Controls;
using FileMonitor.Configuration.Tool.Controls.Prototype;

namespace FileMonitor.Configuration.Tool
{
    public partial class Form1 : Form
    {

        private string currentFileName;
        XElement root;
        public Form1()
        {
            InitializeComponent();
            //  InitTree();
        }

        #region Title Menu
        private void newMenuTrip_Click(object sender, EventArgs e)
        {
            FolderBrowserDialog folderDialog = new FolderBrowserDialog();
            folderDialog.ShowNewFolderButton = true;
            folderDialog.RootFolder = Environment.SpecialFolder.Desktop;
            folderDialog.ShowNewFolderButton = true;
             
            folderDialog.ShowDialog();
            string path = folderDialog.SelectedPath;
            string filePath = path + "/AppConfig.XML";
            if (System.IO.File.Exists(filePath))
            {
                MessageBox.Show("The file named APPConfig.XML is Existed in this folder!");
            }
            else
            {
                using (System.IO.StreamWriter sw = new System.IO.StreamWriter(filePath))
                {
                    sw.WriteLine("<appConfig>");

                    sw.WriteLine("<typeProviders>");

                    sw.WriteLine("<add key=\"TXTMonitor\" value=\"TXTMonitor.Process,TXTMonitor\" />");
                    sw.WriteLine("<add key=\"XLSMonitor\" value=\"XLSMonitor.Process,XLSMonitor\" />");

                    sw.WriteLine("</typeProviders>");

                    sw.WriteLine("<specialValues>");
                    sw.WriteLine("</specialValues>");

                    sw.WriteLine("<connectionStrings>");
                    sw.WriteLine("</connectionStrings>");

                    sw.WriteLine("<processProviders>");
                    sw.WriteLine("<processes>");
                    sw.WriteLine("</processes>");
                    sw.WriteLine("</processProviders>");

                    sw.WriteLine("<businessLogicPeocesses>");
                    sw.WriteLine("<procedureProcesses>");
                    sw.WriteLine("</procedureProcesses>");
                    sw.WriteLine("<cSharpProcesses>");
                    sw.WriteLine("</cSharpProcesses>");
                    sw.WriteLine("</businessLogicPeocesses>");

                    sw.WriteLine("</appConfig>");
                }
                currentFileName = filePath;
                root = XElement.Load(filePath);
                InitNodesList(filePath);
                InitTree();
            }
        }

        private void openMenuTrip_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.FileOk += new CancelEventHandler(openFileDialog_FileOk);
            openFileDialog.Filter = "XML Files (.xml)|*.xml";
            openFileDialog.ShowDialog();

        }

        void openFileDialog_FileOk(object sender, CancelEventArgs e)
        {
            string filePath = (sender as OpenFileDialog).FileName;
            InitNodesList(filePath);
            InitTree();
        }

        private void InitNodesList(string filePath)
        {
            currentFileName = filePath;
            root = XElement.Load(filePath);
            Providers.XMLProvider provider = new XMLProvider(filePath);

            #region Init DB List
            dbList = provider.GetAllDataBase();
            #endregion

            #region Init Type List
            Dictionary<string, Type> dicTypes = provider.GetAllTypes();
            if (typeList == null)
            {
                typeList = new Dictionary<string, string>();
            }
            typeList.Clear();
            dicTypes.ToList().ForEach((item) =>
            {
                string assName = item.Value.Assembly.FullName.Substring(0, item.Value.Assembly.FullName.IndexOf(","));
                typeList.Add(item.Key, item.Value.FullName + "," + assName);
            });
            #endregion

            #region Init SpecialValueList
            specialValueList = provider.GetAllSpecialValues();
            #endregion

            #region Init Work Process&BizProcess
            this.workProcessList = new Dictionary<string, NameValueCollection>();
            this.procedureProcessList = new Dictionary<string, NameValueCollection>();
            this.csharpProcessList = new Dictionary<string, NameValueCollection>();
            
            if (root != null)
            {
                #region Init Work Process
                root.Element("processProviders").Element("processes").Elements("add")
                  .ToList().ForEach(item =>
                  {
                      string name = item.Attribute("name").Value;
                      NameValueCollection allConfig = new NameValueCollection();
                      item.Attributes().ToList().ForEach(at =>
                      {
                          if (at.Name.LocalName != "name")
                          {
                              allConfig.Add(at.Name.LocalName, at.Value);
                          }
                      });
                      this.workProcessList.Add(name, allConfig);
                  }
              );
                #endregion

                #region Init ProcedureProcess
                root.Element("businessLogicPeocesses").Element("procedureProcesses").Elements("add")
                    .ToList().ForEach(item =>
                    {
                        string name = item.Attribute("name").Value;
                        if (name.StartsWith("Procedure_"))
                        {
                            NameValueCollection allConfig = new NameValueCollection();
                            item.Attributes().ToList().ForEach(at =>
                            {
                                if (at.Name.LocalName != "Name")
                                {
                                    allConfig.Add(at.Name.LocalName, at.Value);
                                }
                            }
                            );
                            this.procedureProcessList.Add(name, allConfig);
                        }
                    }
                );
                #endregion

                #region Init CSharp Process
                root.Element("businessLogicPeocesses").Element("cSharpProcesses").Elements("add")
                    .ToList().ForEach(item =>
                    {
                        string name = item.Attribute("name").Value;
                        if (name.StartsWith("CSharp_"))
                        {
                            NameValueCollection allConfig = new NameValueCollection();
                            item.Attributes().ToList().ForEach(at =>
                            {
                                if (at.Name.LocalName != "Name")
                                {
                                    allConfig.Add(at.Name.LocalName, at.Value);
                                }
                            }
                            );
                            this.csharpProcessList.Add(name, allConfig);
                        }
                    }
                );
                #endregion
            }
            #endregion
        }
        #endregion

        #region Tree Menu
        private void InitTree()
        {
            InitDatabaseNodes();
            InitTypesNodes();
            InitSpecialValueNodes();
            InitWorkProcessNodes();
            InitCSharpProcessNodes();
            InitProcedureProcessNodes();
            this.menuTree.AfterSelect += new TreeViewEventHandler(menuTree_AfterSelect);
            this.menuTree.MouseClick += new MouseEventHandler(menuTree_MouseClick);

        }
        private TreeNode dbRoot;
        private TreeNode typesRoot;
        private TreeNode specialValueRoot;
        private TreeNode csharpRoot;
        private TreeNode procedureRoot;


         Dictionary<string, FileUtility.SqlDataBaseExtender> dbList;
         public Dictionary<string, FileUtility.SqlDataBaseExtender> CurrentDBList
         {
             get { return this.dbList; }
         }
        Dictionary<string, string> typeList;
        private ContextMenuStrip addDbStrip;
        private ContextMenuStrip addTypesStrip;
        private ContextMenuStrip addSpecialValueStrip;
        private ContextMenuStrip addWorkProcessStrip;
        private ContextMenuStrip addProcedureProcessStrip;
        private ContextMenuStrip addCSharpProcessStrip;

        #region Database Config

        private void InitDatabaseNodes()
        {
            dbRoot = this.menuTree.Nodes["dbRoot"];
            if (this.dbList == null)
            {
                this.dbList = new Dictionary<string, FileUtility.SqlDataBaseExtender>();
            }
            addDbStrip = new ContextMenuStrip();
            addDbStrip.Items.Add("Add New Database");
            addDbStrip.Items[0].Click += new EventHandler(addDbStrip_Click);
            BindDatabaseNodes();
        }



        private void BindDatabaseNodes()
        {
            if (dbRoot != null && dbList != null)
            {
                dbRoot.Nodes.Clear();
                dbList.ToList().ForEach((db) =>
                {

                    TreeNodeExt node = new TreeNodeExt(db.Key, 1, 2);
                    node.Value = db.Value.CreateConnection().ConnectionString;
                    dbRoot.Nodes.Add(node);
                });
            }
        }


        void addDbStrip_Click(object sender, EventArgs e)
        {
            FileMonitor.Configuration.Tool.Controls.DatabaseEditor dbEditor = new Controls.DatabaseEditor();
            dbEditor.Save += new Tool.Controls.DatabaseEditor.SaveDBHandler(dbEditor_Save);
            dbEditor.Mode = Mode.Add;
            dbEditor.Delete += new DatabaseEditor.SaveDBHandler(dbEditor_Delete);
            this.contentPanel.Controls.Clear();
            this.lblTitle.Text = " Add New Database";
            this.contentPanel.Controls.Add(dbEditor);
        }

        void dbEditor_Delete(object sender, DBEditorArgs args)
        {
            this.dbList.Remove(args.DababaseName);
            SaveDatabaseListToFile(OP.DELETE, args.DababaseName);
            BindDatabaseNodes();
            this.contentPanel.Controls.Clear();
        }

        void dbEditor_Save(object sender, DBEditorArgs args)
        {
            if (this.dbList == null)
            {
                this.dbList = new Dictionary<string, FileUtility.SqlDataBaseExtender>();
            }

            if (this.dbList.ContainsKey(args.DababaseName))
            {
                if (args.Mode == Mode.Add)
                {
                    MessageBox.Show("The Database Name is Existed");
                }
                else if (args.Mode == Mode.Edit)
                {
                    dbList[args.DababaseName] = new FileUtility.SqlDataBaseExtender(args.ConnString);
                    SaveDatabaseListToFile(OP.UPDATE, args.DababaseName);
                }
            }
            else
            {
                dbList.Add(args.DababaseName, new FileUtility.SqlDataBaseExtender(args.ConnString));
                SaveDatabaseListToFile(OP.ADD, args.DababaseName);
            }
            BindDatabaseNodes();
        }
        #endregion

        #region TypesProvider Config

        private void InitTypesNodes()
        {
            typesRoot = this.menuTree.Nodes["typesRoot"];
            if (this.typeList == null)
            {
                this.typeList = new Dictionary<string, string>();
            }
            addTypesStrip = new ContextMenuStrip();
            addTypesStrip.Items.Add("Add New Type");
            addTypesStrip.Items[0].Click += new EventHandler(addTypesStrip_Click);
            BindTypesNodes();
        }

        private void BindTypesNodes()
        {
            if (typesRoot != null && typeList != null)
            {
                typesRoot.Nodes.Clear();
                typeList.ToList().ForEach((type) =>
                {

                    TreeNodeExt node = new TreeNodeExt(type.Key, 1, 2);
                    node.Value = type.Value;
                    typesRoot.Nodes.Add(node);
                });
            }
        }
        void addTypesStrip_Click(object sender, EventArgs e)
        {
            this.contentPanel.Controls.Clear();
            KeyValueEditor keyValueEditor = new KeyValueEditor();
            keyValueEditor.KeyDispalyName = "TypeName";
            keyValueEditor.ValueDisplayName = "TypeVlaue";
            keyValueEditor.Mode = Mode.Add;
            keyValueEditor.Save += new KeyValueEditor.SaveHandler(keyValueEditor_Save);
            keyValueEditor.Delete += new KeyValueEditor.DeleteHandler(keyValueEditor_Delete);
            this.lblTitle.Text = "Add New Type";
            this.contentPanel.Controls.Add(keyValueEditor);

        }

        void keyValueEditor_Save(object sender, KeyValueSaveArgs args)
        {
            KeyValueEditor editor = sender as KeyValueEditor;
            if (this.typeList.ContainsKey(args.Key))
            {
                if (editor.Mode == Mode.Add)
                {
                    MessageBox.Show("The Type is Existed");
                }
                else if (editor.Mode == Mode.Edit)
                {
                    typeList[args.Key] = args.Value;
                    SaveTypeListToFile(OP.UPDATE, args.Key);
                }
            }
            else
            {
                typeList.Add(args.Key, args.Value);
                SaveTypeListToFile(OP.ADD, args.Key);
            }
            BindTypesNodes();
        }

        void keyValueEditor_Delete(object sender, KeyValueSaveArgs args)
        {
            this.typeList.Remove(args.Key);
            SaveTypeListToFile(OP.DELETE, args.Key);
            BindTypesNodes();
            this.contentPanel.Controls.Clear();
        }
        #endregion

        #region SpecialValue Config
        NameValueCollection specialValueList;
        private void InitSpecialValueNodes()
        {
            specialValueRoot = this.menuTree.Nodes["specialValueRoot"];
            if (this.specialValueList == null)
            {
                this.specialValueList = new NameValueCollection();
            }
            addSpecialValueStrip = new ContextMenuStrip();
            addSpecialValueStrip.Items.Add("Add New SpecialValue");
            addSpecialValueStrip.Items[0].Click += new EventHandler(addSpecialValueStrip_Click);
            BindSpecialValues();
        }

        void addSpecialValueStrip_Click(object sender, EventArgs e)
        {
            this.contentPanel.Controls.Clear();
            KeyValueEditor specialValueEditor = new KeyValueEditor();
            specialValueEditor.KeyDispalyName = "Key";
            specialValueEditor.ValueDisplayName = "Value";
            specialValueEditor.Mode = Mode.Add;
            specialValueEditor.Save += new KeyValueEditor.SaveHandler(specialValueEditor_Save);
            specialValueEditor.Delete += new KeyValueEditor.DeleteHandler(specialValueEditor_Delete);
            this.lblTitle.Text = "Add New Special Value";
            this.contentPanel.Controls.Add(specialValueEditor);
        }

        void specialValueEditor_Delete(object sender, KeyValueSaveArgs args)
        {
            this.specialValueList.Remove(args.Key);
            SaveSpecialValueToFile(OP.DELETE, args.Key);
            BindSpecialValues();
            this.contentPanel.Controls.Clear();
        }

        void specialValueEditor_Save(object sender, KeyValueSaveArgs args)
        {
            KeyValueEditor editor = sender as KeyValueEditor;
            if (this.specialValueList[args.Key] != null)
            {
                if (editor.Mode == Mode.Add)
                {
                    MessageBox.Show("The Type is Existed");
                }
                else if (editor.Mode == Mode.Edit)
                {
                    specialValueList[args.Key] = args.Value;
                    SaveSpecialValueToFile(OP.UPDATE, args.Key);
                }
            }
            else
            {
                specialValueList.Add(args.Key, args.Value);
                SaveSpecialValueToFile(OP.ADD, args.Key);
            }
            BindSpecialValues();
        }

        private void BindSpecialValues()
        {
            if (specialValueRoot != null && specialValueList != null)
            {
                specialValueRoot.Nodes.Clear();
                foreach (string key in specialValueList.Keys)
                {
                    TreeNodeExt node = new TreeNodeExt(key, 1, 2);
                    node.Text = key;
                    node.Value = specialValueList[key];
                    specialValueRoot.Nodes.Add(node);
                }
            }
        }
        #endregion


        #region WorkProcess Config
        Dictionary<string, NameValueCollection> workProcessList;
        TreeNode workProcessRoot;

        private void InitWorkProcessNodes()
        {
            this.workProcessRoot = this.menuTree.Nodes["workRoot"];
            if (this.workProcessList == null)
            {
                this.workProcessList = new Dictionary<string, NameValueCollection>();
            }
            this.addWorkProcessStrip = new ContextMenuStrip();
            this.addWorkProcessStrip.Items.Add("Add New WorkProcess");
            this.addWorkProcessStrip.Items[0].Click += new EventHandler(addWorkProcessStrip_Click);
            BindWorkProcessNodes();
        }

        void addWorkProcessStrip_Click(object sender, EventArgs e)
        {
            WorkProcessEditor workProcessEditor = new WorkProcessEditor();
            workProcessEditor.BindTypeList(this.typeList.Keys.ToList());
            workProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
            workProcessEditor.BindSplitArrList(this.specialValueList.AllKeys.ToList());
            workProcessEditor.Save += new WorkProcessEditor.SaveHandler(workProcessEditor_Save);
            workProcessEditor.Delete += new WorkProcessEditor.DeleteHandler(workProcessEditor_Delete);
            workProcessEditor.Mode = Mode.Add;
            this.contentPanel.Controls.Clear();
            this.lblTitle.Text = "Add New WorkProcess";
            this.contentPanel.Controls.Add(workProcessEditor);
        }

        void workProcessEditor_Delete(object sender, ProccessArgs args)
        {
            this.workProcessList.Remove(args.ProcessName);
            SaveWorkProcessToFile(OP.DELETE, args.ProcessName);
            this.contentPanel.Controls.Clear();
            BindWorkProcessNodes();
        }

        void workProcessEditor_Save(object sender, ProccessArgs args)
        {
            WorkProcessEditor editor = sender as WorkProcessEditor;
            foreach (string extKey in args.ExtendableConfig.Keys)
            {
                args.NormalConfig[extKey] = args.ExtendableConfig[extKey];
            }
            if (this.workProcessList.ContainsKey(args.ProcessName))
            {
                if (editor.Mode == Mode.Edit)
                {
                    this.workProcessList[args.ProcessName] = args.NormalConfig;
                    SaveWorkProcessToFile(OP.UPDATE, args.ProcessName);
                }
                else
                {
                    MessageBox.Show("The WorkProcess is Exsited!!");
                }
            }
            else
            {
                this.workProcessList.Add(args.ProcessName, args.NormalConfig);
                SaveWorkProcessToFile(OP.ADD, args.ProcessName);
            }

            BindWorkProcessNodes();
        }

        private void BindWorkProcessNodes()
        {
            if (this.workProcessRoot != null && this.workProcessList != null)
            {
                this.workProcessRoot.Nodes.Clear();
                this.workProcessList.ToList().ForEach((item) =>
                {
                    string name = item.Key;
                    NameValueCollection allConfig = item.Value;
                    TreeNodeExt node = new TreeNodeExt(name, 1, 2);
                    this.workProcessRoot.Nodes.Add(node);
                });
            }
        }


        #endregion

        #region BizProcess Config
        private Dictionary<string, NameValueCollection> procedureProcessList;

        public Dictionary<string, NameValueCollection> CurrentProcedureProcessList
        {
            get { return this.procedureProcessList; }
        }

        private Dictionary<string, NameValueCollection> csharpProcessList;

        public Dictionary<string, NameValueCollection> CurrentCsharpProcessList
        {
            get { return this.csharpProcessList; }
        }

        private void InitCSharpProcessNodes()
        {
            csharpRoot = this.menuTree.Nodes["bizRoot"].Nodes["cshapRoot"];
            if (this.csharpProcessList == null)
            {
                this.csharpProcessList = new Dictionary<string, NameValueCollection>();
            }
            addCSharpProcessStrip = new ContextMenuStrip();
            addCSharpProcessStrip.Items.Add("Add New CSharp Process");
            addCSharpProcessStrip.Items[0].Click += new EventHandler(addCSharpProcessStrip_Click);
            BindCSharpProcessNodes();
        }

        private void BindCSharpProcessNodes()
        {
            if (csharpRoot != null && csharpProcessList != null)
            {
                csharpRoot.Nodes.Clear();
                csharpProcessList.ToList().ForEach((p) =>
                {
                    TreeNodeExt node = new TreeNodeExt(p.Key, 1, 2);
                    csharpRoot.Nodes.Add(node); 
                });
            }
        }

        void addCSharpProcessStrip_Click(object sender, EventArgs e)
        {
            CSharpProcessEditor cSharpProcessEditor = new CSharpProcessEditor();
            cSharpProcessEditor.BindTypeList(this.typeList.Keys.ToList());
            cSharpProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
            cSharpProcessEditor.Save += new ProcessEditorBase.SaveHandler(cSharpProcessEditor_Save);
            cSharpProcessEditor.Delete += new ProcessEditorBase.DeleteHandler(cSharpProcessEditor_Delete);
            cSharpProcessEditor.Mode = Mode.Add;
            this.contentPanel.Controls.Clear();
            this.lblTitle.Text = "Add New  CSharp Process";
            this.contentPanel.Controls.Add(cSharpProcessEditor);
            
        }

        void cSharpProcessEditor_Delete(object sender, ProccessArgs args)
        {
            this.csharpProcessList.Remove(args.ProcessName);
            SaveCSharpProcessToFile(OP.DELETE, args.ProcessName);
            this.contentPanel.Controls.Clear();
            BindCSharpProcessNodes();
        }

        void cSharpProcessEditor_Save(object sender, ProccessArgs args)
        {
            CSharpProcessEditor editor = sender as CSharpProcessEditor;
            foreach (string extKey in args.ExtendableConfig.Keys)
            {
                args.NormalConfig[extKey] = args.ExtendableConfig[extKey];
            }
            if (this.csharpProcessList.ContainsKey(args.ProcessName))
            {
                if (editor.Mode == Mode.Edit)
                {
                    this.csharpProcessList[args.ProcessName] = args.NormalConfig;
                    SaveCSharpProcessToFile(OP.UPDATE, args.ProcessName);
                }
                else
                {
                    MessageBox.Show("The WorkProcess is Exsited!!");
                }
            }
            else
            {
                this.csharpProcessList.Add(args.ProcessName, args.NormalConfig);
                SaveCSharpProcessToFile(OP.ADD, args.ProcessName);
            }
            BindCSharpProcessNodes();

        }

        private void InitProcedureProcessNodes()
        {
            procedureRoot = this.menuTree.Nodes["bizRoot"].Nodes["procedureRoot"];
            if (this.procedureProcessList == null)
            {
                this.procedureProcessList = new Dictionary<string, NameValueCollection>();
            }
            addProcedureProcessStrip = new ContextMenuStrip();
            addProcedureProcessStrip.Items.Add("Add New Procedure Process");
            addProcedureProcessStrip.Items[0].Click += new EventHandler(addProcedureProcessStrip_Click);
            BindProcedureProcessNodes();
        }

        private void BindProcedureProcessNodes()
        {
            if (procedureRoot != null && procedureProcessList != null)
            {
                procedureRoot.Nodes.Clear();
                procedureProcessList.ToList().ForEach((p) =>
                {
                    TreeNodeExt node = new TreeNodeExt(p.Key, 1, 2);
                    procedureRoot.Nodes.Add(node);
                });
            }
        }


        void addProcedureProcessStrip_Click(object sender, EventArgs e)
        {
            ProcedureProcessEditor procedureProcessEditor = new ProcedureProcessEditor();
            procedureProcessEditor.BindTypeList(this.typeList.Keys.ToList());
            procedureProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
            procedureProcessEditor.Save+=new ProcessEditorBase.SaveHandler(procedureProcessEditor_Save);
            procedureProcessEditor.Delete +=new ProcessEditorBase.DeleteHandler(procedureProcessEditor_Delete);
            procedureProcessEditor.Mode = Mode.Add;
            this.contentPanel.Controls.Clear();
            this.lblTitle.Text = "Add New  Procedure Process";
            this.contentPanel.Controls.Add(procedureProcessEditor);
        }

        void procedureProcessEditor_Save(object sender, ProccessArgs args)
        {
            ProcedureProcessEditor editor = sender as ProcedureProcessEditor;
            foreach (string extKey in args.ExtendableConfig.Keys)
            {
                args.NormalConfig[extKey] = args.ExtendableConfig[extKey];
            }
            if (this.procedureProcessList.ContainsKey(args.ProcessName))
            {
                if (editor.Mode == Mode.Edit)
                {
                    this.procedureProcessList[args.ProcessName] = args.NormalConfig;
                    SaveProcedureProcessToFile(OP.UPDATE, args.ProcessName);
                }
                else
                {
                    MessageBox.Show("The WorkProcess is Exsited!!");
                }
            }
            else
            {
                this.procedureProcessList.Add(args.ProcessName, args.NormalConfig);
                SaveProcedureProcessToFile(OP.ADD, args.ProcessName);
               
            }
            BindProcedureProcessNodes();

        }

        void procedureProcessEditor_Delete(object sender, ProccessArgs args)
        {
            this.procedureProcessList.Remove(args.ProcessName);
            SaveProcedureProcessToFile(OP.DELETE, args.ProcessName);
            this.contentPanel.Controls.Clear();
            BindProcedureProcessNodes();
        }

        #endregion



        void menuTree_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                TreeNode selectNode = menuTree.GetNodeAt(e.X, e.Y);
                if (selectNode == this.dbRoot)
                {
                    menuTree.ContextMenuStrip = addDbStrip;
                }
                else if (selectNode == this.typesRoot)
                {
                    menuTree.ContextMenuStrip = addTypesStrip;
                }
                else if (selectNode == this.specialValueRoot)
                {
                    menuTree.ContextMenuStrip = addSpecialValueStrip;
                }
                else if (selectNode == this.workProcessRoot)
                {
                    menuTree.ContextMenuStrip = addWorkProcessStrip;
                }
                else if (selectNode == this.csharpRoot)
                {
                    menuTree.ContextMenuStrip = addCSharpProcessStrip;
                }
                else if (selectNode == this.procedureRoot)
                {
                    menuTree.ContextMenuStrip = addProcedureProcessStrip;
                }

                else
                {
                    menuTree.ContextMenuStrip = null;
                }
            }

        }

        void menuTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Parent == this.dbRoot)
            {
                TreeNodeExt node = e.Node as TreeNodeExt;
                string connstr = node.Value;
                this.contentPanel.Controls.Clear();
                DatabaseEditor dbEditor = new DatabaseEditor();
                dbEditor.Mode = Mode.Edit;
                dbEditor.BindConnString(connstr, node.Text);
                dbEditor.Save += new DatabaseEditor.SaveDBHandler(dbEditor_Save);
                dbEditor.Delete += new DatabaseEditor.SaveDBHandler(dbEditor_Delete);
                this.contentPanel.Controls.Add(dbEditor);
                this.lblTitle.Text = " Edit Database";
            }
            if (e.Node.Parent == this.typesRoot)
            {
                TreeNodeExt node = e.Node as TreeNodeExt;
                string typeValue = node.Value;
                string typeName = node.Text;
                KeyValueEditor keyValueEditor = new KeyValueEditor();
                keyValueEditor.KeyDispalyName = "TypeName";
                keyValueEditor.ValueDisplayName = "TypeValue";
                keyValueEditor.Mode = Mode.Edit;
                keyValueEditor.BindData(typeName, typeValue);
                keyValueEditor.Save += new KeyValueEditor.SaveHandler(keyValueEditor_Save);
                keyValueEditor.Delete += new KeyValueEditor.DeleteHandler(keyValueEditor_Delete);
                this.contentPanel.Controls.Clear();
                this.contentPanel.Controls.Add(keyValueEditor);
                this.lblTitle.Text = " Edit TypeValue";
            }
            if (e.Node.Parent == this.specialValueRoot)
            {
                TreeNodeExt node = e.Node as TreeNodeExt;
                string key = node.Text;
                string value = node.Value;
                KeyValueEditor specialValueEditor = new KeyValueEditor();
                specialValueEditor.KeyDispalyName = "Key";
                specialValueEditor.ValueDisplayName = "Value";
                specialValueEditor.Mode = Mode.Edit;
                specialValueEditor.BindData(key, value);
                specialValueEditor.Save += new KeyValueEditor.SaveHandler(specialValueEditor_Save);
                specialValueEditor.Delete += new KeyValueEditor.DeleteHandler(specialValueEditor_Delete);
                this.contentPanel.Controls.Clear();
                this.contentPanel.Controls.Add(specialValueEditor);
                this.lblTitle.Text = " Edit Special Value";
            }
            if (e.Node.Parent == this.workProcessRoot)
            {
                string key = e.Node.Text;
                WorkProcessEditor workProcessEditor = new WorkProcessEditor();
                workProcessEditor.BindTypeList(this.typeList.Keys.ToList());
                workProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
                workProcessEditor.BindSplitArrList(this.specialValueList.AllKeys.ToList());
                workProcessEditor.BindData(key, this.workProcessList[key], this.workProcessList[key]);
                workProcessEditor.Save += new WorkProcessEditor.SaveHandler(workProcessEditor_Save);
                workProcessEditor.Delete += new WorkProcessEditor.DeleteHandler(workProcessEditor_Delete);
                workProcessEditor.Mode = Mode.Edit;
                this.contentPanel.Controls.Clear();
                this.contentPanel.Controls.Add(workProcessEditor);
                this.lblTitle.Text = " Edit WorkProcess";

            }
            if (e.Node.Parent == this.csharpRoot)
            {
                string key = e.Node.Text;
                CSharpProcessEditor cSharpProcessEditor = new CSharpProcessEditor();
                cSharpProcessEditor.BindTypeList(this.typeList.Keys.ToList());
                cSharpProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
                cSharpProcessEditor.BindData(key, this.csharpProcessList[key], this.csharpProcessList[key]);
                cSharpProcessEditor.Save+=new ProcessEditorBase.SaveHandler(cSharpProcessEditor_Save);
                cSharpProcessEditor.Delete+=new ProcessEditorBase.DeleteHandler(cSharpProcessEditor_Delete);
                cSharpProcessEditor.Mode = Mode.Edit;
                this.contentPanel.Controls.Clear();
                this.contentPanel.Controls.Add(cSharpProcessEditor);
                this.lblTitle.Text = " Edit CSharp Process";
            }
            if (e.Node.Parent == this.procedureRoot)
            {
                string key = e.Node.Text;
                ProcedureProcessEditor procedureProcessEditor = new ProcedureProcessEditor();
                procedureProcessEditor.BindTypeList(this.typeList.Keys.ToList());
                procedureProcessEditor.BindDatabaseList(this.dbList.Keys.ToList());
                procedureProcessEditor.BindData(key, this.procedureProcessList[key], this.procedureProcessList[key]);
                procedureProcessEditor.Save += new ProcessEditorBase.SaveHandler(procedureProcessEditor_Save);
                procedureProcessEditor.Delete += new ProcessEditorBase.DeleteHandler(procedureProcessEditor_Delete);
                procedureProcessEditor.Mode = Mode.Edit;
                this.contentPanel.Controls.Clear();
                this.contentPanel.Controls.Add(procedureProcessEditor);
                this.lblTitle.Text = " Edit Procedure Process";
            }
        }

     

        #endregion

        #region Save to File

        
        


        private void SaveDatabaseListToFile(OP op,string key)
        {
            XElement dbElement = root.Element("connectionStrings");
            string connstr = "";
            switch (op)
            {
                case OP.ADD:
                    connstr=this.dbList[key].CreateConnection().ConnectionString;
                      XElement e1 = new XElement("add");
                      e1.SetAttributeValue("name", key);
                      e1.SetAttributeValue("connectionString", connstr);
                      e1.SetAttributeValue("providerName", "System.Data.SqlClient");
                    dbElement.Add(e1);
                    break;
                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("name").Value == key).Remove();
                    break;
                case OP.UPDATE:
                    connstr = this.dbList[key].CreateConnection().ConnectionString;
                    dbElement.Elements()
                        .Where(e3 => e3.Attribute("name").Value == key)
                        .First()
                        .Attribute("connectionString").Value = connstr;
                    break;
            }
             
            root.Save(currentFileName);
        }


        private void SaveTypeListToFile(OP op, string key)
        {
            XElement dbElement = root.Element("typeProviders");
            string value = "";
            switch (op)
            {
                case OP.ADD:
                    value = this.typeList[key];
                    XElement e1 = new XElement("add");
                    e1.SetAttributeValue("key", key);
                    e1.SetAttributeValue("value", value);
                    dbElement.Add(e1);
                    break;
                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("key").Value == key).Remove();
                    break;
                case OP.UPDATE:
                    value = this.typeList[key];
                    dbElement.Elements()
                        .Where(e3 => e3.Attribute("key").Value == key)
                        .First()
                        .Attribute("value").Value = value;
                    break;
            }
            root.Save(currentFileName);
        }

        private void SaveSpecialValueToFile(OP op, string key)
        {
            XElement dbElement = root.Element("specialValues");
            string value = "";
            switch (op)
            {
                case OP.ADD:
                    value = this.specialValueList[key];
                    XElement e1 = new XElement("add");
                    e1.SetAttributeValue("key", key);
                    e1.SetAttributeValue("value", value);
                    dbElement.Add(e1);
                    break;
                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("key").Value == key).Remove();
                    break;
                case OP.UPDATE:
                    value = this.specialValueList[key];
                    dbElement.Elements()
                        .Where(e3 => e3.Attribute("key").Value == key)
                        .First()
                        .Attribute("value").Value = value;
                    break;
            }
            root.Save(currentFileName);
        }

        private void SaveWorkProcessToFile(OP op, string key)
        {
            XElement dbElement = root.Element("processProviders").Element("processes");
            NameValueCollection values = null;
            switch (op)
            {
                case OP.ADD:
                    values = this.workProcessList[key];
                    XElement e1 = new XElement("add");
                    e1.SetAttributeValue("name", key);
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e1.SetAttributeValue(k, values[k]);
                        }
                    }
                    dbElement.Add(e1);
                    break;

                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("name").Value == key).Remove();
                    break;

                case OP.UPDATE:
                    values = this.workProcessList[key];
                    XElement e3 = dbElement.Elements()
                        .Where(e => e.Attribute("name").Value == key)
                        .First();
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e3.SetAttributeValue(k, values[k]);
                        }
                    }
                    break;
            }
            root.Save(currentFileName);
        }


        private void SaveProcedureProcessToFile(OP op, string key)
        {
            XElement dbElement = root.Element("businessLogicPeocesses").Element("procedureProcesses");
            NameValueCollection values = null;
            switch (op)
            {
                case OP.ADD:
                    values = this.procedureProcessList[key];
                    XElement e1 = new XElement("add");
                    e1.SetAttributeValue("name", key);
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e1.SetAttributeValue(k, values[k]);
                        }
                    }
                    dbElement.Add(e1);
                    break;

                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("name").Value == key).Remove();
                    break;

                case OP.UPDATE:
                    values = this.procedureProcessList[key];
                    XElement e3 = dbElement.Elements()
                        .Where(e => e.Attribute("name").Value == key)
                        .First();
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e3.SetAttributeValue(k, values[k]);
                        }
                    }
                    break;
            }
            root.Save(currentFileName);
        }

        private void SaveCSharpProcessToFile(OP op, string key)
        {
            XElement dbElement = root.Element("businessLogicPeocesses").Element("cSharpProcesses");
            NameValueCollection values = null;
            switch (op)
            {
                case OP.ADD:
                    values = this.csharpProcessList[key];
                    XElement e1 = new XElement("add");
                    e1.SetAttributeValue("name", key);
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e1.SetAttributeValue(k, values[k]);
                        }
                    }
                    dbElement.Add(e1);
                    break;

                case OP.DELETE:
                    dbElement.Elements().Where(e2 => e2.Attribute("name").Value == key).Remove();
                    break;

                case OP.UPDATE:
                    values = this.csharpProcessList[key];
                    XElement e3 = dbElement.Elements()
                        .Where(e => e.Attribute("name").Value == key)
                        .First();
                    foreach (string k in values.Keys)
                    {
                        if (k.ToUpper() != "PROCESSNAME")
                        {
                            e3.SetAttributeValue(k, values[k]);
                        }
                    }
                    break;
            }
            root.Save(currentFileName);
        }

        #endregion

        private void exitMenuTrip_Click(object sender, EventArgs e)
        {
            this.Dispose();
            this.Close();
        }
    }

    enum OP
    {
        ADD,
        UPDATE,
        DELETE

    }

}